

#include "Reader.h"
#include "phalMfdfEVx.h"
#include "phpalCt/phpalCt.h"
#include "reader_samav3.h"
#include "log/log2.h"
#include "config/config3.h"

extern phhalHw_SamAV3_DataParams_t stHal_SamAv3;

phalMfdfEVx_SamAV3_NonX_DataParams_t  palMfdfEVx_SamAV3;

static uint8_t aTMIBuffer[280];//Buffer for DESFire TMI collection
static uint8_t aCmdBuffer[280];//Buffer for DESFire commands
static phTMIUtils_t	pTMI;
int reader_mfdf_init(void){
    phStatus_t  status = 0;	
	
	/* Set the generic pointer */
	phpalI14443p3a_Sw_DataParams_t *ppalI14443p3a = (phpalI14443p3a_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P3A);
	phpalI14443p4_Sw_DataParams_t *ppalI14443p4 = (phpalI14443p4_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_ISO14443P4);
	phpalMifare_Sw_DataParams_t *ppalMifare= (phpalMifare_Sw_DataParams_t *) phNfcLib_GetDataParams(PH_COMP_PAL_MIFARE);
	
	phTMIUtils_Init(&pTMI,aTMIBuffer,sizeof(aTMIBuffer));
	
	//INIT DESFire Params
	status = phalMfdfEVx_SamAV3_NonX_Init(
				&palMfdfEVx_SamAV3,
				sizeof(palMfdfEVx_SamAV3),
				&stHal_SamAv3,
				ppalMifare,
				&pTMI,
				aCmdBuffer,
				sizeof(aCmdBuffer)
			 );
	
	if(status != PH_ERR_SUCCESS) {
		LOG2_ERR("\n DESFire Init failed! status = 0x%04X", status);
	}

	return status;
}

static void* reader_mfdf_get_pal_mfdfevx(uint8_t evid){
    void* palMfdfEVx;
    if(evid == PHAL_MFDFEVX_SAMAV3_NONX_ID){
        palMfdfEVx = &palMfdfEVx_SamAV3;
    }
    else{
        palMfdfEVx = phNfcLib_GetDataParams(PH_COMP_AL_MFDFEVX);
    }
    return palMfdfEVx;
}

#define PH_MFDF_CHECK_SUCCESS(x)              \
    if ((x) != PH_ERR_SUCCESS)        \
{                                     \
    LOG2_ERR("\nLine: %d   Error - (0x%04X) has occurred : 0xCCEE CC-Component ID, EE-Error code. Refer-ph_Status.h\n ", __LINE__, (x)); \
    return (x);                       \
}
/* save 24-bit little endian data to host memory
 * argument is pointer to memory block
 */
static uint32_t le24toh(uint8_t data[/*3*/])
{
  return ((uint32_t) data[0] | ((uint32_t) data[1] << 8) | 
          ((uint32_t) data[2] << 16));
}

int reader_mfdf_aid_to_32(uint8_t* aid_buf, uint8_t aid_num, uint32_t* aid32, uint8_t aid_max_num)
{
	const uint8_t* aid_end = aid_buf + aid_num;
	uint8_t* aid = aid_buf;
	int i;
	for(i = 0; (aid < aid_end) && (i < aid_max_num); i++) {
		/* extract AID, which comes in Little Endian */
		aid32[i] = le24toh(aid);
		aid += 3;
	}
	
	return i;
}

int reader_mfdf_get_version(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t * pVerInfo                                                      /**< [Out] The version information of the product. */
    )
{
    void* palMfdfEVx = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetVersion(palMfdfEVx, pVerInfo);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_select_application(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_SELECT_PRIMARY_APP
                                                                                 *          \arg #PHAL_MFDFEVX_SELECT_SECOND_APP
                                                                                 */
        uint8_t * pAid,                                                         /**< [In] The primary application identifier to be used. Will be of 3 bytes with LSB first.
                                                                                 *          \c If application 01 need to be selected then the Aid will be 01 00 00.
                                                                                 */
        uint8_t * pAid2                                                         /**< [In] The secondary application identifier to be used. Will be of 3 bytes with LSB first.
                                                                                 *          \c If application 01 need to be selected then the Aid will be 01 00 00.
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_SelectApplication(palMfdfEVx, bOption, pAid, pAid2);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


/**
 * \brief ISO Select. This command is implemented in compliance with ISO/IEC 7816-4.
 *
 * \return Status code
 * \retval #PH_ERR_SUCCESS Operation successful.
 * \retval Other Depending on implementation and underlying component.
 */

int reader_mfdf_iso_select_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */        
        uint8_t bOption,                                                        /**< [In] Option for return / no return of FCI.
                                                                                 *          \arg #PHAL_MFDFEVX_FCI_RETURNED
                                                                                 *          \arg #PHAL_MFDFEVX_FCI_NOT_RETURNED
                                                                                 */
        uint8_t bSelector,                                                      /**< [In] The selector to be used.
                                                                                 *          \arg #PHAL_MFDFEVX_SELECTOR_0
                                                                                 *          \arg #PHAL_MFDFEVX_SELECTOR_1
                                                                                 *          \arg #PHAL_MFDFEVX_SELECTOR_2
                                                                                 *          \arg #PHAL_MFDFEVX_SELECTOR_3
                                                                                 *          \arg #PHAL_MFDFEVX_SELECTOR_4
                                                                                 */
        uint8_t * pFid,                                                         /**< [In] The ISO File number to be selected. */
        uint8_t * pDFname,                                                      /**< [In] The ISO DFName to be selected. Valid only when bOption = 0x04. */
        uint8_t bDFnameLen,                                                     /**< [In] Length of bytes available in DFname buffer. */
        uint8_t bExtendedLenApdu,                                               /**< [In] Flag for Extended Length APDU. */
        uint8_t ** ppFCI,                                                       /**< [Out] The FCI information returned by the PICC. */
        uint16_t * pwFCILen                                                     /**< [Out] Length of bytes available in FCI buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_IsoSelectFile(palMfdfEVx, bOption, bSelector, pFid, pDFname, bDFnameLen, bExtendedLenApdu, ppFCI, pwFCILen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}



int reader_mfdf_get_application_ids(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] One of the below options.
                                                                                 *          \arg #PH_EXCHANGE_DEFAULT
                                                                                 *          \arg #PH_EXCHANGE_RXCHAINING
                                                                                 */
        uint8_t ** pAidBuff,                                                    /**< [Out] The available identifiers of the application(s). */
        uint8_t * pNumAid                                                       /**< [Out] The number of available application(s). */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetApplicationIDs(palMfdfEVx, PH_EXCHANGE_DEFAULT, pAidBuff, pNumAid);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_create_application(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Option to represent the present of ISO information.
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_INFO_NOT_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_DF_NAME_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_DF_NAME_AVAILABLE
                                                                                 */
        uint8_t * pAid,                                                         /**< [In] The application identifier to be used. Will be of 3 bytes with LSB first.
                                                                                 *          \c If application 01 need to be created then the Aid will be 01 00 00.
                                                                                 */
        uint8_t bKeySettings1,                                                  /**< [In] Application Key settings. */
        uint8_t bKeySettings2,                                                  /**< [In] Additional key settings.  */
        uint8_t bKeySettings3,                                                  /**< [In] Additional key settings.  */
        uint8_t * pKeySetValues,                                                /**< [In] The Key set values for the application. Should as mentioned below.\n
                                                                                 *          \c Byte0 = AKS ver\n
                                                                                 *          \c Byte1 = Number of Keysets\n
                                                                                 *          \c Byte2 = MaxKeysize\n
                                                                                 *          \c Byte3 = Application KeySet Settings.
                                                                                 */
        uint8_t * pISOFileId,                                                   /**< [In] ISO File ID to be used. Will be two bytes. */
        uint8_t * pISODFName,                                                   /**< [In] ISO DF Name to be used. Will be 16 bytes and can also be NULL based on the option. */
        uint8_t bISODFNameLen                                                   /**< [In] Length of bytes available in ISODFName buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateApplication( palMfdfEVx, bOption, pAid, bKeySettings1, bKeySettings2,
            bKeySettings3, pKeySetValues, pISOFileId, pISODFName, bISODFNameLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_delete_application(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        
        uint8_t * pAid                                                          /**< [In] The application identifier to be used. Will be of 3 bytes with LSB first. \n
                                                                                 *          \c If application 01 need to be deleted then the Aid will be 01 00 00.
                                                                                 */
        , uint8_t * pDAMMAC,                                                    /**< [In] [Optional, present if PICCDAMAuthKey or NXPDAMAuthKey is used for authentication]
                                                                                 *        The MAC calculated by the card issuer to allow delegated application deletion.
                                                                                 */
        uint8_t bDAMMAC_Len                                                     /**< [In] Length of bytes available in DAMMAC buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_DeleteApplication(palMfdfEVx, pAid, pDAMMAC, bDAMMAC_Len);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_authenticate(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR | #PHAL_MFDFEVX_DIV_OPTION_2K3DES_HALF
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR | #PHAL_MFDFEVX_DIV_OPTION_2K3DES_FULL
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_CMAC
                                                                                 */
        uint16_t wKeyNo,                                                        /**< [In] Key number in keystore of software or SAM. */
        uint16_t wKeyVer,                                                       /**< [In] Key version in the key store of software or SAM. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen                                                         /**< [In] Length of diversification input max 31B. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_Authenticate(palMfdfEVx, wOption, wKeyNo, wKeyVer, bKeyNoCard, pDivInput, bDivLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_authenticate_iso(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR | #PHAL_MFDFEVX_DIV_OPTION_2K3DES_HALF
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR | #PHAL_MFDFEVX_DIV_OPTION_2K3DES_FULL
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_CMAC
                                                                                 */
        uint16_t wKeyNo,                                                        /**< [In] Key number in keystore of software or SAM. */
        uint16_t wKeyVer,                                                       /**< [In] Key version in the key store of software or SAM. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen                                                         /**< [In] Length of diversification input max 31B. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_AuthenticateISO(palMfdfEVx, wOption, wKeyNo, wKeyVer, bKeyNoCard, pDivInput, bDivLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_authenticate_aes(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_CMAC
                                                                                 */
        uint16_t wKeyNo,                                                        /**< [In] Key number in keystore of software or SAM. */
        uint16_t wKeyVer,                                                       /**< [In] Key version in the key store of software or SAM. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen                                                         /**< [In] Length of diversification input max 31B. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_AuthenticateAES(palMfdfEVx, wOption, wKeyNo, wKeyVer, bKeyNoCard, pDivInput, bDivLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_authenticate_ev2(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bFirstAuth,                                                     /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_AUTH_FIRST
                                                                                 *          \arg #PHAL_MFDFEVX_AUTH_NONFIRST
                                                                                 */
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_ENCR
                                                                                 *          \arg #PHAL_MFDFEVX_DIV_METHOD_CMAC
                                                                                 */
        uint16_t wKeyNo,                                                        /**< [In] Key number in keystore of software or SAM. */
        uint16_t wKeyVer,                                                       /**< [In] Key version in the key store of software or SAM. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen,                                                        /**< [In] Length of diversification input max 31B. */
        uint8_t bLenPcdCapsIn,                                                  /**< [In] Length of PcdCapsIn. Always zero for NonFirst authentication. */
        uint8_t *bPcdCapsIn,                                                    /**< [In] PCD Capabilities. Upto 6 bytes. */
        uint8_t *bPcdCapsOut,                                                   /**< [Out] PCD Capabilities. 6 bytes. */
        uint8_t *bPdCapsOut                                                     /**< [Out] PD Capabilities. 6 bytes. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_AuthenticateEv2(palMfdfEVx, bFirstAuth, wOption, wKeyNo, wKeyVer, bKeyNoCard, pDivInput, bDivLen,
		bLenPcdCapsIn, bPcdCapsIn, bPcdCapsOut, bPdCapsOut);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;	
}

int reader_mfdf_get_file_ids(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t * pFid,                                                         /**< [Out] The buffer containing the available file ID(s). Buffer should be 32 bytes. */
        uint8_t * bNumFid                                                       /**< [Out] The length of bytes available in Fid buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetFileIDs(palMfdfEVx, pFid, bNumFid);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_delete_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bFileNo                                                         /**< [In] The file number to be deleted.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_DeleteFile(palMfdfEVx, bFileNo);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_get_file_settings(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bFileNo,                                                        /**< [In] The file number for which the setting to be retrieved.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pFSBuffer,                                                    /**< [Out] The buffer containing the settings. */
        uint8_t * bBufferLen                                                    /**< [Out] The length of bytes available in FSBuffer buffer. */
){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetFileSettings(palMfdfEVx, bFileNo, pFSBuffer, bBufferLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_read_data(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 *
                                                                                 *          \c #PH_EXCHANGE_RXCHAINING: To be Or'd with the above option
                                                                                 *              flag if Chaining status is returned.
                                                                                 */
        uint8_t bIns,                                                           /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_APPLICATION_CHAINING
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_CHAINING
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number from where the data to be read.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pOffset,                                                      /**< [In] The offset from where the data should be read. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 need to be offset then it will be 10 00 00.
                                                                                 */
        uint8_t * pLength,                                                      /**< [In] The number of bytes to be read. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be read then it will be 10 00 00. \n
                                                                                 *          \c If complete file need to be read then it will be 00 00 00.
                                                                                 */
        uint8_t ** ppRxdata,                                                    /**< [Out] The data retuned by the PICC. */
        uint16_t * pRxdataLen                                                   /**< [Out] Length of bytes available in RxData buffer. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ReadData(palMfdfEVx, bOption, bIns, bFileNo, pOffset, pLength, ppRxdata, pRxdataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_write_data(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bIns,                                                           /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_APPLICATION_CHAINING
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_CHAINING
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the data to be written.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pOffset,                                                      /**< [In] The offset from where the data should be written. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 need to be offset then it will be 10 00 00.
                                                                                 */
        uint8_t * pTxData,                                                      /**< [In] The data to be written to the PICC. */
        uint8_t * pTxDataLen                                                    /**< [In] The number of bytes to be written. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be written then it will be 10 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_WriteData(palMfdfEVx, bOption, bIns, bFileNo, pOffset, pTxData, pTxDataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_get_value(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number for which the value to the retrieved.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pValue                                                        /**< [Out] The value returned by the PICC. The buffer should be 4 bytes. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetValue(palMfdfEVx, bCommOption, bFileNo, pValue);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_credit(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the value should be credited.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pValue                                                        /**< [In] The value to be credited. Will be of 4 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be credited then it will be 10 00 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_Credit(palMfdfEVx, bCommOption, bFileNo, pValue);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_debit(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the value should be debited.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pValue                                                        /**< [Out] The value to be debited. Will be of 4 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be debited then it will be 10 00 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_Debit(palMfdfEVx, bCommOption, bFileNo, pValue);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_limited_credit(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the value should be credited.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pValue                                                        /**< [Out] The value to be credited. Will be of 4 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be credited then it will be 10 00 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_LimitedCredit(palMfdfEVx, bCommOption, bFileNo, pValue);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_free_mem(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t * pMemInfo                                                      /**< [Out] Current free memory available. Will be of 3 bytes with LSB first. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_FreeMem(palMfdfEVx, pMemInfo);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_format(
        uint8_t evid                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_Format(palMfdfEVx);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_create_std_data_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Option to represent the present of ISO information.
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_INFO_NOT_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pISOFileId,                                                   /**< [In] ISO File ID to be used. Will be two bytes. */
        uint8_t bFileOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MFC_MAPPING_ENABLED
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_SDM_MIRRORING_ENABLED
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t * pFileSize                                                     /**< [In] The size of the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the FileSize will be 10 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateStdDataFile(palMfdfEVx, bOption, bFileNo, pISOFileId, bFileOption, pAccessRights, pFileSize);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_create_backup_data_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Option to represent the present of ISO information.
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_INFO_NOT_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pISOFileId,                                                   /**< [In] ISO File ID to be used. Will be two bytes. */
        uint8_t bFileOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MFC_MAPPING_ENABLED
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t * pFileSize                                                     /**< [In] The size of the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the FileSize will be 10 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateBackupDataFile(palMfdfEVx, bOption, bFileNo, pISOFileId, bFileOption, pAccessRights, pFileSize);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_create_value_file(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t bCommSett,                                                      /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MFC_MAPPING_ENABLED
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t * pLowerLmit,                                                   /**< [In] The lower limit for the file. Will be of 4 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the value will be 10 00 00 00.
                                                                                 */
        uint8_t * pUpperLmit,                                                   /**< [In] The upper limit for the file. Will be of 4 bytes with LSB first.
                                                                                 *          \c If size 0x20 need to be created then the value will be 20 00 00 00.
                                                                                 */
        uint8_t * pValue,                                                       /**< [In] The initial value. Will be of 4 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the value will be 10 00 00 00.
                                                                                 */
        uint8_t bLimitedCredit                                                  /**< [In] One of the below values.
                                                                                 *          \arg #PHAL_MFDFEVX_ENABLE_LIMITEDCREDIT
                                                                                 *          \arg #PHAL_MFDFEVX_ENABLE_FREE_GETVALUE
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateValueFile(palMfdfEVx, 
		bFileNo, bCommSett, pAccessRights, pLowerLmit, pUpperLmit, pValue, bLimitedCredit);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_create_linear_record_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Option to represent the present of ISO information.
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_INFO_NOT_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pISOFileId,                                                   /**< [In] ISO File ID to be used. Will be two bytes. */
        uint8_t bCommSett,                                                      /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t * pRecordSize,                                                  /**< [In] The size of the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the RecordSize will be 10 00 00.
                                                                                 */
        uint8_t * pMaxNoOfRec                                                   /**< [In] The maximum number of record in the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x04 need to be created then the value will be 04 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateLinearRecordFile(palMfdfEVx, 
		bOption, bFileNo, pISOFileId, bCommSett, pAccessRights, pRecordSize, pMaxNoOfRec);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}
	
int reader_mfdf_create_cyclic_record_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Option to represent the present of ISO information.
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_INFO_NOT_AVAILABLE
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_FILE_ID_AVAILABLE
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pISOFileId,                                                   /**< [In] ISO File ID to be used. Will be two bytes. */
        uint8_t bCommSett,                                                      /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t * pRecordSize,                                                  /**< [In] The size of the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x10 need to be created then the RecordSize will be 10 00 00.
                                                                                 */
        uint8_t * pMaxNoOfRec                                                   /**< [In] The maximum number of record in the file. Will be of 3 bytes with LSB first.
                                                                                 *          \c If size 0x04 need to be created then the value will be 04 00 00.
                                                                                 */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateCyclicRecordFile(palMfdfEVx, 
		bOption, bFileNo, pISOFileId, bCommSett, pAccessRights, pRecordSize, pMaxNoOfRec);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_create_transaction_mac_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint16_t wOption,                                                       /**< [In] One of the below options. Only applicable for SAM S / X component
                                                                                 *          \arg #PHAL_MFDFEVX_CREATE_TMAC_FILE_DIV_OFF
                                                                                 *          \arg #PHAL_MFDFEVX_CREATE_TMAC_FILE_DIV_ON
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to be created.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t bCommSett,                                                      /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint16_t wKeyNo,                                                        /**< [In] Key number in SAM keystore. For software is not applicable. */
        uint8_t bKeyType,                                                       /**< [In] The TMKeyOption and should be always #PHAL_MFDFEVX_KEY_TYPE_AES128. */
        uint8_t * bTMKey,                                                       /**< [In] The 16 byte key value to be stored in the PICC. This is applicable for Software only. */
        uint8_t bTMKeyVer,                                                      /**< [In] The version for the key to be stored in the PICC. This is applicable for Software and SAM. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivInputLength                                                 /**< [In] Length of diversification input max 31B. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CreateTransactionMacFile(palMfdfEVx, 
		wOption, bFileNo, bCommSett, pAccessRights, wKeyNo, bKeyType,
		bTMKey, bTMKeyVer, pDivInput, bDivInputLength);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_commit_transaction(        
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMIT_TXN_OPTION_NOT_EXCHANGED
                                                                                 *          \arg #PHAL_MFDFEVX_COMMIT_TXN_NO_TMC_TMV_RETURNED
                                                                                 *          \arg #PHAL_MFDFEVX_COMMIT_TXN_TMC_TMV_RETURNED
                                                                                 */
        uint8_t * pTMC,                                                         /**< [Out] The increased value as stored in FileType.TransactionMAC. \n
                                                                                 *          \c 4 byte Transaction MAC counter value.
                                                                                 */
        uint8_t * pTMV                                                          /**< [Out] 8 bytes Transaction MAC value. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_CommitTransaction(palMfdfEVx, bOption, pTMC, pTMV);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_abort_transaction(
        uint8_t evid                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_AbortTransaction(palMfdfEVx);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_get_card_uid(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bExchangeOption,                                                /**< [In] Flag to indicate whether the parameter information
                                                                                 *        bOption to be exchanged to PICC or not.
                                                                                 *          \arg PHAL_MFDFEVX_GET_CARD_UID_EXCHANGE_OPTION_OFF
                                                                                 *          \arg PHAL_MFDFEVX_GET_CARD_UID_EXCHANGE_OPTION_ON
                                                                                 */
        uint8_t bOption,                                                        /**< [In] One of the below options.
                                                                                 *          \arg PHAL_MFDFEVX_GET_CARD_UID_OPTION_NUID_NOT_RETURNED
                                                                                 *          \arg PHAL_MFDFEVX_GET_CARD_UID_OPTION_NUID_RETURNED
                                                                                 */
        uint8_t * pUid                                                          /**< [Out] The complete UID of the PICC. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetCardUID(palMfdfEVx, bExchangeOption, bOption, pUid);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}


int reader_mfdf_get_key_version(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bKeyNo,                                                         /**< [In] Key number of the targeted key. ORed with one of the below options
                                                                                 *          \arg #PHAL_MFDFEVX_SAI
                                                                                 *          \arg #PHAL_MFDFEVX_KEYSETNO_NOT_PRESENT
                                                                                 *          \arg #PHAL_MFDFEVX_KEYSETNO_PRESENT
                                                                                 */
        uint8_t bKeySetNo,                                                      /**< [In] Key set number. ORed with one of the below options
                                                                                 *          \arg #PHAL_MFDFEVX_RETRIVE_KEY_VERSION
                                                                                 *          \arg #PHAL_MFDFEVX_RETRIVE_KEY_SET_VERSION
                                                                                 */
        uint8_t * pKeyVersion,                                                  /**< [Out] Key set versions of the selected application ordered by ascending
                                                                                 *         key set number, i.e. starting with the AKS.
                                                                                 */
        uint8_t * bRxLen                                                        /**< [Out] Length of bytes available in KeyVersion buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetKeyVersion(palMfdfEVx, bKeyNo, bKeySetNo, pKeyVersion, bRxLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_get_key_settings(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t * pKeySettings,                                                 /**< [Out] Returns the key settings. Can be 2 or 3 bytes. */
        uint8_t * bRespLen                                                      /**< [Out] Length bytes available in KeySettings buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_GetKeySettings(palMfdfEVx, pKeySettings, bRespLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_change_key_settings(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bKeySettings                                                    /**< [In] New key settings to be updated. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ChangeKeySettings(palMfdfEVx, bKeySettings);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_change_key(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY_ONERND
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY_ONERND
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY |
                                                                                 *               #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY |
                                                                                 *               #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY_ONERND | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY_ONERND
                                                                                 */
        uint16_t wOldKeyNo,                                                     /**< [In] Old key number in keystore of software or SAM. */
        uint16_t wOldKeyVer,                                                    /**< [In] Old key version in keystore of software or SAM. */
        uint16_t wNewKeyNo,                                                     /**< [In] New key number in keystore of software or SAM. */
        uint16_t wNewKeyVer,                                                    /**< [In] New key version in keystore of software or SAM. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen                                                         /**< [In] Length of diversification input max 31B. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ChangeKey(palMfdfEVx, wOption, wOldKeyNo, wOldKeyVer, wNewKeyNo, wNewKeyVer, bKeyNoCard, pDivInput, bDivLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_change_key_ev2(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint16_t wOption,                                                       /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_NO_DIVERSIFICATION
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY_ONERND
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY_ONERND
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY |
                                                                                 *               #PHAL_MFDFEVX_CHGKEY_DIV_METHOD_CMAC
                                                                                 *          \arg #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY |
                                                                                 *               #PHAL_MFDFEVX_CHGKEY_DIV_NEW_KEY_ONERND | #PHAL_MFDFEVX_CHGKEY_DIV_OLD_KEY_ONERND
                                                                                 */
        uint16_t wOldKeyNo,                                                     /**< [In] Old key number in keystore of software or SAM. */
        uint16_t wOldKeyVer,                                                    /**< [In] Old key version in keystore of software or SAM. */
        uint16_t wNewKeyNo,                                                     /**< [In] New key number in keystore of software or SAM. */
        uint16_t wNewKeyVer,                                                    /**< [In] New key version in keystore of software or SAM. */
        uint8_t bKeySetNo,                                                      /**< [In] Key set number within targeted application. */
        uint8_t bKeyNoCard,                                                     /**< [In] Key number on card. ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator. */
        uint8_t * pDivInput,                                                    /**< [In] Diversification input. Can be NULL. */
        uint8_t bDivLen                                                         /**< [In] Length of diversification input max 31B. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ChangeKeyEv2(palMfdfEVx, wOption, wOldKeyNo, wOldKeyVer, wNewKeyNo, wNewKeyVer, bKeySetNo, bKeyNoCard, pDivInput, bDivLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_change_file_settings(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Indicates the mode of communication to be used while exchanging the data to PICC.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below flags if required.
                                                                                 *          \arg #PHAL_MFDFEVX_EXCHANGE_ADD_INFO_BUFFER_COMPLETE
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] File number for which the setting need to be updated.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t bFileOption,                                                    /**< [In] New communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ENC
                                                                                 *        \n
                                                                                 *        Ored with one of the below flags if required.
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_SDM_MIRRORING_ENABLED
                                                                                 *          \arg #PHAL_MFDFEVX_FILE_OPTION_TMCLIMIT_PRESENT
                                                                                 */
        uint8_t * pAccessRights,                                                /**< [In] The new access right to be applied for the file. Should be 2 byte. */
        uint8_t bAddInfoLen,                                                    /**< [In] Complete length consisting of\n
                                                                                 *          - If bOption is not having #PHAL_MFDFEVX_EXCHANGE_ADD_INFO_BUFFER_COMPLETE set\n
                                                                                 *              - Additional Access Rights if bFileOption & #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT\n
                                                                                 *              - TMC Limit                if bFileOption & #PHAL_MFDFEVX_FILE_OPTION_TMCLIMIT_PRESENT\n
                                                                                 *                  - If TMCLimit and AddARs is not available, bAddInfoLen = 0\n
                                                                                 *                  - If AddARs is not available,              bAddInfoLen = 4\n
                                                                                 *                  - If TMCLimit is not available,            bAddInfoLen = 0 - 7\n
                                                                                 *                  - If TMCLimit and AddARs is available,     bAddInfoLen = ( ( 0 - 7 ) + 4 )
                                                                                 *
                                                                                 *          - If bOption is having #PHAL_MFDFEVX_EXCHANGE_ADD_INFO_BUFFER_COMPLETE set, where N is SDM information\n
                                                                                 *              - Additional Access Rights if bFileOption & #PHAL_MFDFEVX_FILE_OPTION_ADDITIONAL_AR_PRESENT\n
                                                                                 *              - SDM Information          if bFileOption & #PHAL_MFDFEVX_FILE_OPTION_SDM_MIRRORING_ENABLED\n
                                                                                 *              - TMC Limit                if bFileOption & #PHAL_MFDFEVX_FILE_OPTION_TMCLIMIT_PRESENT\n
                                                                                 *                  - If all the 3 are not available,                 bAddInfoLen = 0
                                                                                 *                  - If AddARs is not available,                     bAddInfoLen = N + 4\n
                                                                                 *                  - If TMCLimit is not available,                   bAddInfoLen = ( ( 0 - 7 ) * 2 ) + N\n
                                                                                 *                  - If SDM is not available,                        bAddInfoLen = ( ( 0 - 7 ) * 2 ) + 4\n
                                                                                 *                  - If all the 3 are available,                     bAddInfoLen = ( ( ( 0 - 7 ) * 2 ) + N + 4)
                                                                                 *
                                                                                 *
                                                                                 */
        uint8_t * pAddInfo                                                      /**< [In] Buffer should contain the following information. \n
                                                                                 *          \c [Additional access rights] || [SDMOption || SDM AccessRights || VCUIDOffset ||
                                                                                 *             SDMReadCtrOffset || PICCDataOffset || SDMACInputOffset || SDMENCOffset ||
                                                                                 *             SDMENCLength || SDMMACOffset] || [TMCLimit]
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ChangeFileSettings(palMfdfEVx, bOption, bFileNo, bFileOption, pAccessRights, bAddInfoLen, pAddInfo);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_read_records(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 *
                                                                                 *          \c #PH_EXCHANGE_RXCHAINING: To be Or'd with the above option
                                                                                 *              flag if Chaining status is returned.
                                                                                 */
        uint8_t bIns,                                                           /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_APPLICATION_CHAINING
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_CHAINING
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number from where the data to be read.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pRecNo,                                                       /**< [In] 3 bytes LSB first. Record number of the newest record targeted, starting to count
                                                                                 *        from the latest record written.
                                                                                 */
        uint8_t * pRecCount,                                                    /**< [In] 3 bytes LSB first. Number of records to be read. If 0x00 00 00, then all the records are read. */
        uint8_t * pRecSize,                                                     /**< [In] The number of bytes to be read. Will be of 3 bytes with LSB first. */
        uint8_t ** ppRxdata,                                                    /**< [Out] The data retuned by the PICC. */
        uint16_t * pRxdataLen                                                   /**< [Out] Length of bytes available in RxData buffer. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ReadRecords(palMfdfEVx, bCommOption, bIns, bFileNo, pRecNo, pRecCount, pRecSize, ppRxdata, pRxdataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_write_record(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bIns,                                                           /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_APPLICATION_CHAINING
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_CHAINING
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the data should be written.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pOffset,                                                      /**< [In] The offset from where the data should be written. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 need to be offset then it will be 10 00 00.
                                                                                 */
        uint8_t * pData,                                                        /**< [In] The data to be written to the PICC. */
        uint8_t * pDataLen                                                      /**< [In] The number of bytes to be written. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be written then it will be 10 00 00.
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_WriteRecord(palMfdfEVx, bCommOption, bIns, bFileNo, pOffset, pData, pDataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_update_record(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bCommOption,                                                    /**< [In] Communication settings for the file.
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_PLAIN
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_MACD
                                                                                 *          \arg #PHAL_MFDFEVX_COMMUNICATION_ENC
                                                                                 */
        uint8_t bIns,                                                           /**< [In] One of the below options.
                                                                                 *          \arg #PHAL_MFDFEVX_APPLICATION_CHAINING
                                                                                 *          \arg #PHAL_MFDFEVX_ISO_CHAINING
                                                                                 */
        uint8_t bFileNo,                                                        /**< [In] The file number to which the data should be written.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t * pRecNo,                                                       /**< [In] Record number. Records are numbered starting with the latest record written. */
        uint8_t * pOffset,                                                      /**< [In] Starting position for the update operationwithin the targeted record. */
        uint8_t * pData,                                                        /**< [In] The data to be written to the PICC. */
        uint8_t * pDataLen                                                      /**< [In] The number of bytes to be written. Will be of 3 bytes with LSB first.
                                                                                 *          \c If 0x10 bytes need to be written then it will be 10 00 00.
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_UpdateRecord(palMfdfEVx, bCommOption, bIns, bFileNo, pRecNo, pOffset, pData, pDataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_clear_record_file(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bFileNo                                                         /**< [In] The file number to be cleared.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_ClearRecordFile(palMfdfEVx, bFileNo);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_finalize_key_set(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bKeySetNo,                                                      /**< [In] Key set number within targeted application.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t bKeySetVersion                                                  /**< [In] KeySet version of the key set to be finalized. */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_FinalizeKeySet(palMfdfEVx, bKeySetNo, bKeySetVersion);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_initialize_key_set(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bKeySetNo,                                                      /**< [In] Key set number within targeted application.
                                                                                 *        ORed with #PHAL_MFDFEVX_SAI to indicate secondary application indicator.
                                                                                 */
        uint8_t bKeyType                                                        /**< [In] One of the below mentioned options.
                                                                                 *          \arg #PHAL_MFDFEVX_KEY_TYPE_2K3DES
                                                                                 *          \arg #PHAL_MFDFEVX_KEY_TYPE_3K3DES
                                                                                 *          \arg #PHAL_MFDFEVX_KEY_TYPE_AES128
                                                                                 */
    )
{
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_InitializeKeySet(palMfdfEVx, bKeySetNo, bKeyType);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

int reader_mfdf_set_configuration(
        uint8_t evid,                                                           /** PHAL_MFDFEVX_SAMAV3_NONX_ID or PHAL_MFDFEVX_SW_ID */
        uint8_t bOption,                                                        /**< [In] Configuration Option.
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION0
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION1
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION2
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION3
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION4
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION5
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTION6
                                                                                 *          \arg #PHAL_MFDFEVX_SET_CONFIG_OPTIONC
                                                                                 */
        uint8_t * pData,                                                        /**< [In] Data for the option specified.*/
        uint8_t bDataLen                                                        /**< [In] Length of bytes available in Data buffer. */
    ){
	void* palMfdfEVx  = reader_mfdf_get_pal_mfdfevx(evid);
	phStatus_t status = phalMfdfEVx_SetConfiguration(palMfdfEVx, bOption, pData, bDataLen);
	PH_MFDF_CHECK_SUCCESS(status);
	return 0;
}

uint8_t reader_mfdf_get_evid(uint8_t key_id){
	return (key_id & KID_FLASH_MASK) ? PHAL_MFDFEVX_SW_ID :PHAL_MFDFEVX_SAMAV3_NONX_ID;
}

